package sanshui.system.trade.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import sanshui.system.trade.db.entity.TradeHisOpPos;
import sanshui.system.trade.factory.distribute.DistributeManager;
import sanshui.system.trade.factory.trade.strategy.StrategyCallType;
import sanshui.system.trade.model.PositionAccModel;
import sanshui.system.trade.model.TradeHisPositionModel;

import java.util.ArrayList;
import java.util.List;

@Slf4j
public class ReportUtil {
    /**
     * 计算某个品种的胜率
     * 默认为单品种
     */
    public static int winRateX100(List<TradeHisPositionModel> posList, String currentTime) throws Exception {
        if (posList.isEmpty()) {
            return 0;
        }

        String tsCodeLast = posList.get(0).getTargetCode();
        for (TradeHisOpPos tradeHisOpPos : posList) {
            String tsCode = tradeHisOpPos.getTargetCode();
            if (tsCodeLast.equalsIgnoreCase(tsCode)) {
                tsCodeLast = tsCode;
            } else {
                log.error("计算胜率时，品种不单一");
                return 0;
            }
        }

        // 按时间排序，从小到大
        posList.sort((o1, o2) -> Boolean.compare(CommonTimeUtil.before(o1.getOpTime(), o2.getOpTime()), false));

        PositionAccModel positionAccModel = new PositionAccModel();
        String opType = posList.get(0).getOpType();
        if (StrategyCallType.SELL.name().equalsIgnoreCase(opType)) {
            log.error("计算胜率时，排序后，第一次操作为卖出");
            return 0;
        }
        // 清仓一次，计算一次胜率
        int opTotal = 0;
        int winNum = 0;
        List<TradeHisOpPos> opPosTemp = new ArrayList<>();
        for (TradeHisOpPos tradeHisOpPos : posList) {
            opType = tradeHisOpPos.getOpType();
            if (StrategyCallType.BUY.name().equalsIgnoreCase(opType)) {
                positionAccModel.setNumTotal(positionAccModel.getNumTotal() + tradeHisOpPos.getTradeNum());
            }
            if (StrategyCallType.SELL.name().equalsIgnoreCase(opType)) {
                positionAccModel.setNumTotal(positionAccModel.getNumTotal() - tradeHisOpPos.getTradeNum());
            }
            if (positionAccModel.getNumTotal() == 0) {
                opTotal++;
                if (ReportUtil.isWinCompute(opPosTemp)) {
                    winNum++;
                }
                positionAccModel.setNumTotal(0L);
                opPosTemp.clear();
            }
            opPosTemp.add(tradeHisOpPos);
        }
        if (0 == opTotal){
            return 0;
        }
        return winNum * 100 / opTotal;
    }

    private static boolean isWinCompute(List<TradeHisOpPos> opPosList) {
        long value = 0L;
        for (TradeHisOpPos tradeHisOpPos : opPosList) {
            String opType = tradeHisOpPos.getOpType();
            if (StrategyCallType.BUY.name().equalsIgnoreCase(opType)) {
                value += tradeHisOpPos.getTradeNum() * tradeHisOpPos.getTradePrice();
            }
            if (StrategyCallType.SELL.name().equalsIgnoreCase(opType)) {
                value -= tradeHisOpPos.getTradeNum() * tradeHisOpPos.getTradePrice();
            }
        }
        return value <= 0;
    }
}
